header {
/*******************************************************************************
 * Copyright (c) 2008 Nels E. Beckman.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Nels E. Beckman - initial API and implementation
 *******************************************************************************/
 
package edu.cmu.cs.nbeckman.wptranslator.parser;
 
import edu.cmu.cs.nbeckman.wptranslator.*;
import java.util.*;
}


class WPDataParser extends Parser;
first returns [Document d]
{ Element el;
  d = null;
}
: el=elementList EOF { d = new Document(el); };  

elementList returns [Element e]
{ List<Element> l = new LinkedList<Element>();
  e = null;
  Element e1;
}
: ( e1=element { l.add(e1); } )+ { e = new ElementList(l); };

element returns [Element e]
   {
     e = null;
     Element e1;
     String t1;
   }
   : t1=text { e = new Text(t1); }
   | BBOLD e1=elementList EBOLD { e = new BoldedElement(e1); }
   | (BCENTER|WEIRDBCENTER) e1=elementList ECENTER { e = new CenteredElement(e1); }
   | HRETURN { e = LineBreak.singleton(); } 
   | BUNDERLINE e1=elementList EUNDERLINE { e = new UnderlinedElement(e1); }
   | BINDENT HRETURN ch:. BINDENT e1=elementList EINDENT . OTHERENDINDENT EINDENT 
       { e=new Indent(e1,ch.getText().toCharArray()[0]); } /* FIXME: This is a disaster waiting to happen. */
   | WEIRDBDINDENT e1=elementList WEIRDEDINDENT { e=new DoubleIndent(e1); }
   | TAB { e=Tab.singleton(); }
   ;
   
text returns [String r]
   {
     r = "";
     StringBuffer buf = new StringBuffer();
     String ch = "";
     String pu = "";
   }
   : ( ch=character { buf.append(ch); } | pu=punctuation { buf.append(pu); } )+ { r = buf.toString(); };    

punctuation returns [String r]
   {
     r = "";
   }
   : HYPHEN { r = "-"; }
   | PERIOD { r = "."; }
   | SPACE  { r = " "; }
   ;
character returns [String r]
   {
     r = "";
   }
   : l:LLETTER { r = l.getText(); }
   | u:ULETTER { r = u.getText(); }
   | o:OTHER   { r = o.getText(); }
   ; 

class WPDataLexer extends Lexer;
options {
    charVocabulary = '\u0000'..'\u00FF';
}

TAB : '\11'; /* Tab */
HRETURN : '\12'; /* Hard return. Also used in Begin Indent */
OTHERENDINDENT : '\112'; /* This other character that appears in the end indent. */ 
BBOLD : '\235' ; /* Begin bold */
EBOLD : '\234' ; /* End bold */   
WEIRDBCENTER : '\303' '\0' '\52' '\33' '\303' ; 
              /* This is the begin center that seems to actually show up. */
BCENTER : '\303' ; /* Begin center */
ECENTER : '\203'; /* End center */
BUNDERLINE : '\224'; /* Begin underline */
EUNDERLINE : '\225'; /* End underline */
BINDENT : '\314'; /* Begin single indent */
EINDENT : '\336'; /* End indent */
WEIRDBDINDENT : '\340' '\0' '\5' '\340'; /* Begin double indent. What does this mean? */
WEIRDEDINDENT : '\336' '\17' '\105' '\336'; /* End Double indent */
ULETTER : 'A'..'Z';
LLETTER : 'a'..'z';
DIGIT  : '0'..'9';
HYPHEN : '\251';   
PERIOD : '\56';
SPACE  : '\40';
OTHER : .; /* Just assume everything else is ascii */